﻿#region HeaderComments
// ***********************************************************************************************************************************************
// Copyright (C) # YEAR # # York #
// 作    者：# CaiTao #
// 创建日期：# CREATIONDATE #
// 功能描述：# 动画组件基类 #
// 修改记录：# MODIFICATIONRECORD #
// ***********************************************************************************************************************************************
#endregion

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using DG.Tweening;
using Sirenix.Serialization;
using Sirenix.OdinInspector;

namespace AnimationComponent
{
    public interface IPlay
    {
        void PlayAnimation();
        void PlayBackwards();
        void PlayForward();
    }

    public interface IPlayAsync
    {
        IEnumerator PlayAnimationAsync();
        IEnumerator PlayBackwardsAsync();
        IEnumerator PlayForwardAsync();
    }

    public interface IAnimatiomn: IPlay, IPlayAsync
    {
        Tween tween { get; set; }
        Ease ease { get; set; }
        PanelsState panelState { get; set; }
        PanelsState aniPrePanelState { get; set; }

        float animatorTime { get; set; }

        AnimationGroup animationGroup { get; set; }

        Action onPlay { get; set; }
        Action onComplete { get; set; }
        Action onStepComplete { get; set; }
        Action onKill { get; set; }
        void CreateAnimation();
       
        IAnimatiomn AddPlayEvent(Action playCall);
        IAnimatiomn AddCompleteEvent(Action completeCall);
        IAnimatiomn AddStepCompleteEvent(Action completeCall);
        IAnimatiomn AddKillEvent(Action killCall);
        IAnimatiomn RemovePlayEvent(Action playCall);
        IAnimatiomn RemoveCompleteEvent(Action completeCall);
        IAnimatiomn RemoveStepCompleteEvent(Action completeCall);
        IAnimatiomn RemoveKillEvent(Action killCall);
        IAnimatiomn RemoveAllPlayEvent();
        IAnimatiomn RemoveAllCompleteEvent();
        IAnimatiomn RemoveAllStepCompleteEvent();
        IAnimatiomn RemoveAllKillEvent();
    }
    public enum MoveAxis
    {
        X,
        Y,
    }

    /// <summary>
    /// 动画实现方式
    /// </summary>
    public enum AnimationPattern
    {
        ButtonClick,   //按钮点击
        DoubleClick,   //鼠标双击
    }
    /// <summary>
    /// 面板状态类型
    /// </summary>
    public enum PanelsState
    {
        STATUS1,       //状态1
        STATUS2,       //状态2
        ANIMATIONING,  //动画中
    }

    public class AnimationBase : SerializedMonoBehaviour, IAnimatiomn
    {
        public Tween tween { get; set; }
        [OdinSerialize]
        public Ease ease { get; set; } = Ease.Linear;
        /// <summary>
        /// 定义状态1到状态2为向前播放，定义状态2到状态1为向后播放
        /// </summary>
        public PanelsState panelState { get; set; } = PanelsState.STATUS1;
        public PanelsState aniPrePanelState { get; set; }
        [OdinSerialize]
        public float animatorTime { get; set; } = 2;
        [OdinSerialize]
        public AnimationGroup animationGroup { get; set; }
        public Action onPlay { get; set; }
        public Action onComplete { get; set; }
        public Action onStepComplete { get; set; }
        public Action onKill { get; set; }

        public virtual void Awake()
        {
            AddToAnimationGround();
            CreateAnimation();
        }

        public void AddToAnimationGround()
        {
            if (animationGroup != null)
            {
                animationGroup.animations.Add(this);
            }
        }

        public virtual IAnimatiomn AddPlayEvent(Action playCall)
        {
            onPlay += playCall;
            return this;
        }

        public IAnimatiomn RemoveAllPlayEvent()
        {
            onPlay = null ;
            return this;
        }

        public virtual IAnimatiomn RemovePlayEvent(Action playCall)
        {
            onPlay -= playCall;
            return this;
        }

        public virtual IAnimatiomn AddCompleteEvent(Action completeCall)
        {
            onComplete += completeCall;
            return this;
        }

        public virtual IAnimatiomn RemoveCompleteEvent(Action completeCall)
        {
            onComplete -= completeCall;
            return this;
        }

        public IAnimatiomn RemoveAllCompleteEvent()
        {
            onComplete = null;
            return this;
        }

        public virtual IAnimatiomn AddStepCompleteEvent(Action stepCompleteCall)
        {
            onStepComplete += stepCompleteCall;
            return this;
        }
        public virtual IAnimatiomn RemoveStepCompleteEvent(Action stepCompleteCall)
        {
            onStepComplete -= stepCompleteCall;
            return this;
        }

        public IAnimatiomn RemoveAllStepCompleteEvent()
        {
            onStepComplete = null;
            return this;
        }

        public virtual IAnimatiomn AddKillEvent(Action killCall)
        {
            onKill += killCall;
            return this;
        }
        public virtual IAnimatiomn RemoveKillEvent(Action killCall)
        {
            onKill -= killCall;
            return this;
        }

        public IAnimatiomn RemoveAllKillEvent()
        {
            onKill = null;
            return this;
        }

        public virtual void CreateAnimation()
        {
        }

        public virtual void PlayAnimation()
        {
            if (panelState == PanelsState.ANIMATIONING) return;
            switch (panelState)
            {
                case PanelsState.STATUS1:
                    PlayForward();
                    break;
                case PanelsState.STATUS2:
                    PlayBackwards();
                    break;
            }
        }

        public virtual IEnumerator PlayAnimationAsync()
        {
            if (panelState == PanelsState.ANIMATIONING) yield break;
            switch (panelState)
            {
                case PanelsState.STATUS1:
                   yield return PlayForwardAsync();
                    break;
                case PanelsState.STATUS2:
                    yield return PlayBackwardsAsync();
                    break;
            }
        }

        public virtual void PlayForward()
        {
            if (tween.IsPlaying()) return;
            tween.PlayForward();
        }

        public virtual IEnumerator PlayForwardAsync()
        {
            if (tween.IsPlaying()) yield break;
            tween.PlayForward();
            yield return new WaitForSeconds(animatorTime);
        }

        public virtual void PlayBackwards()
        {
            if (tween.IsPlaying()) return;
            tween.PlayBackwards();
        }

        public virtual IEnumerator PlayBackwardsAsync()
        {
            if (tween.IsPlaying()) yield break;
            tween.PlayBackwards();
            yield return new WaitForSeconds(animatorTime);
        }

        
    }
}

